package WizardTD.element;

import WizardTD.App;
import WizardTD.CountdownTimer;
import WizardTD.DataConstruct;
import WizardTD.board.ManaProcessBar;
import lombok.Data;
import WizardTD.*;
import processing.core.PApplet;
import processing.core.PImage;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HustleLr
 * @version 1.0.0
 */
@Data
public class MonsterBox {
    private List<Monster> monsters = new ArrayList<>();

    public List<DestroyMonster> destroyMonsters = new ArrayList<>();

    public List<DestroyMonster> removeDestroyMonsters = new ArrayList<>();
    private List<Monster> removeMonsters = new ArrayList<>();
    private List<Monster> arriveMonsters = new ArrayList<>();
    private List<Monster> subManaMonsters = new ArrayList<>();

    // 计时器
    private Map<Integer, CountdownTimer> countdownTimerMap;
    private Map<Integer, CountdownTimer> waitTimerMap;

    private PApplet pApplet;

    private PImage pImage;

    private DataConstruct dataConstruct;
    private float wait = Integer.MAX_VALUE;

    private boolean isStart = false;

    /**
     * 已生成怪物数量
     */
    private int havaMonsterNum;

    /**
     * 当前帧数
     */
    private int currentFrame = 0;

    private int waveCount = 0;
    private int monsterCount = 0;

    public MonsterBox(DataConstruct dataConstruct, PApplet pApplet) {
        this.dataConstruct = dataConstruct;
        this.pApplet = pApplet;
        this.countdownTimerMap = dataConstruct.getCountdownTimerMap();
        this.waitTimerMap = dataConstruct.getWaitTimerMap();
    }

    public void drawMonster() {
        execMonsterDisplay(dataConstruct);
        checkMonsterArrived();
        monsters.removeAll(removeMonsters);
        destroyMonsters.removeAll(removeDestroyMonsters);
        monsters.forEach(monster -> monster.draw(pApplet));
        destroyMonsters.forEach(destroyMonster -> destroyMonster.draw(pApplet));
    }

    public void checkMonsterArrived() {
        List<Monster> removeMonsterlist = monsters.stream().filter(Monster::isArriveLast).collect(Collectors.toList());
        removeMonsters.addAll(removeMonsterlist);
        subManaMonsters.addAll(removeMonsterlist);
        Iterator<Monster> iterator = subManaMonsters.iterator();
        ManaProcessBar mana = App.board.getManaProcessBar();
        while (iterator.hasNext()) {
            Monster monster = iterator.next();
            if (subManaMonsters.contains(monster)) {
                mana.subMana(monster.getMana_gained_on_kill());
                iterator.remove(); // 安全地从 subManaMonsters 移除怪物
            }
        }
    }

    private void execMonsterDisplay(DataConstruct dataConstruct) {
        Random random = new Random();
        Map<Integer, Double> waveIntervalMap = dataConstruct.waveIntervalMap;
        // 获取读取的配置
        LevelAndWaveConfig levelAndWaveConfig = dataConstruct.getLevelAndWaveConfig();
        // 获取波浪
        List<Wave> waves = levelAndWaveConfig.getWaves();

        if (App.waveNum < waves.size()) {
            Wave wave = levelAndWaveConfig.getWaves().get(App.waveNum);
            // 怪物类型
            List<Monster> monsterTypeList = wave.getMonsters();
            // 间隔时间
            Double intervalSecond = waveIntervalMap.get(App.waveNum);
            // 每波总数
            int perWaveCountNum = monsterTypeList.stream().mapToInt(Monster::getQuantity).sum();
            int randomIndex = random.nextInt(monsterTypeList.size());
            Monster monsterType = monsterTypeList.get(randomIndex);
            generateMonster(dataConstruct, levelAndWaveConfig, intervalSecond, perWaveCountNum, monsterType, wave);
        }
    }

    private void generateMonster(DataConstruct dataConstruct, LevelAndWaveConfig levelAndWaveConfig, Double intervalSecond, int perWaveCountNum, Monster monsterType, Wave wave) {
        CountdownTimer countdownTimer = countdownTimerMap.get(App.waveNum);
        double generateFps = intervalSecond * App.FPS;
        List<Coordinate> shortestPath = dataConstruct.shortestPath;
        // 开始坐标
        Coordinate startSite = shortestPath.get(0);
        waveCount++;
        if (waveCount >= wave.getPre_wave_pause() * App.FPS) {
            isStart = true;
            monsterCount++;
            if (monsterCount % Math.round(generateFps) == 0) {
                if (havaMonsterNum < perWaveCountNum) {
                    // 每个怪物的生成时间
                    monsters.add(new Monster(startSite.col * App.CELLSIZE, (startSite.row + 1) * App.CELLSIZE, this.dataConstruct.imgMap.get(monsterType.getType()), monsterType, dataConstruct));
                    this.havaMonsterNum++;
                } else if (countdownTimer.getCurrentTime() <= 0) {
                    App.waveNum++;
                    this.havaMonsterNum = 0;
                    monsterCount = 0;
                    waveCount = 0;
                    isStart = false;
                    dataConstruct.levelAndWaveConfig.setWaveNums(levelAndWaveConfig.getWaveNums() - 1);
                }
            }

        }
        countdownTimer.setStart(isStart);
        dataConstruct.levelAndWaveConfig.setCountdownTimer(countdownTimer);
    }
}
